Skip to content

Puhhh/scripts

Repository files navigation

Docker Security Scripts

Коллекция Bash-скриптов для управления Docker/Podman-образами и их статического анализа безопасности. Скрипты покрывают полный цикл работы с образами — от скачивания и упаковки до аудита безопасности и отображения отчётов об уязвимостях.

Автор: Aleksei Blinov


Содержание


Обзор скриптов

Скрипт Назначение Инструмент
images-load.sh Загрузка образов из .tar, перетеггирование и опциональный push в реестр docker / podman
images-save.sh Pull образов для заданной платформы и сохранение в .tar docker
json-report-pretty.sh Цветной вывод JSON-отчётов Trivy и Grype с фильтрацией по уровню jq, column
rootless-docker-audit.sh Комплексный аудит rootless-установки Docker docker
image-security-checker.sh Статический анализ безопасности Docker-образов docker, tar

Общие зависимости

Зависимость Используется в
docker images-save, rootless-docker-audit, image-security-checker
docker или podman images-load
jq json-report-pretty
column json-report-pretty
tar image-security-checker
awk image-security-checker
stat image-security-checker
pgrep, ps, lsns, unshare rootless-docker-audit

Установка утилит на Debian/Ubuntu:

sudo apt install jq util-linux

images-load.sh

Описание

Загружает Docker/Podman-образы из .tar-файлов в указанном каталоге. Опционально перетеггирует каждый образ с новым префиксом реестра и предлагает запушить результат.

Скрипт автоматически определяет доступный инструмент — docker или podman.

Расположение

Images Load/images-load.sh

Зависимости

  • docker или podman

Использование

./images-load.sh <путь_к_каталогу_с_tar> [целевой_префикс]
Аргумент Обязательный Описание
путь_к_каталогу Да Каталог, содержащий .tar-файлы образов
целевой_префикс Нет Префикс реестра для перетеггирования (registry.example.com/myproject)

Примеры

Загрузка образов без переименования:

./images-load.sh /opt/images

Загрузка с перетеггированием и push в реестр:

./images-load.sh /opt/images registry.example.com/myproject

После перетеггирования скрипт спросит подтверждение перед push:

👉 Запушить переименованные образы в реестр 'registry.example.com/myproject'? [Y/n]:

Поведение

  • Итерирует все .tar-файлы в указанном каталоге.
  • Если целевой_префикс задан: для каждого загруженного образа вычисляет новый тег вида <prefix>/<name>:<tag> и добавляет его через tag.
  • Если целевой_префикс не задан: образы загружаются с оригинальными тегами без переименования.
  • Если в каталоге нет .tar-файлов, скрипт завершается с предупреждением без ошибки.

images-save.sh

Описание

Скачивает Docker-образы для указанной платформы и сохраняет их как .tar-архивы в текущем каталоге. Принимает образы как аргументы командной строки или из файла со списком.

Расположение

Images Save/images-save.sh

Зависимости

  • docker

Использование

./images-save.sh [-p platform] image1 [image2 ...]
./images-save.sh [-p platform] -f image_list.txt
Опция По умолчанию Описание
-p platform linux/amd64 Целевая платформа (linux/arm64, linux/amd64 и т.д.)
-f image_list.txt Файл со списком образов, по одному на строку

Примеры

Сохранение одного образа для платформы по умолчанию:

./images-save.sh nginx:1.25

Сохранение нескольких образов для ARM:

./images-save.sh -p linux/arm64 nginx:1.25 redis:7 postgres:15

Сохранение образов из файла:

./images-save.sh -f images.txt

Формат файла images.txt:

# Это комментарий — строка игнорируется
nginx:1.25
redis:7

postgres:15

Поведение

  • Пустые строки и строки, начинающиеся с #, в файле-списке пропускаются.
  • Имя результирующего архива формируется из имени образа заменой / и : на _. Например, registry.example.com/myapp:v1.0 сохраняется как registry.example.com_myapp_v1.0.tar.
  • При ошибке во время docker pull или docker save скрипт завершается немедленно (set -e).

json-report-pretty.sh

Описание

Читаемо отображает JSON-отчёты сканеров уязвимостей Trivy и Grype в терминале с цветовой подсветкой по уровню серьёзности и опциональной фильтрацией.

Расположение

JSON Report Pretty/json-report-pretty.sh

Зависимости

  • jq
  • column

Использование

./json-report-pretty.sh <report.json> [--min-severity=LEVEL]
Аргумент / Опция По умолчанию Описание
report.json Путь к JSON-файлу отчёта Trivy или Grype
--min-severity=LEVEL LOW Минимальный уровень серьёзности для отображения

Допустимые значения --min-severity (от наиболее к наименее серьёзному):

CRITICAL  HIGH  MEDIUM  LOW  NEGLIGIBLE  UNKNOWN

Примеры

Отобразить все уязвимости из отчёта Trivy:

./json-report-pretty.sh trivy-report.json

Отобразить только CRITICAL и HIGH:

./json-report-pretty.sh trivy-report.json --min-severity=HIGH

Отобразить отчёт Grype только с CRITICAL:

./json-report-pretty.sh grype-report.json --min-severity=CRITICAL

Создать отчёт Trivy и сразу передать его на отображение:

trivy image --format json -o report.json nginx:latest
./json-report-pretty.sh report.json --min-severity=MEDIUM

Формат вывода

Trivy — столбцы: CVE ID, пакет, версия, уровень, название:

CVE-2024-1234  openssl  3.0.2  CRITICAL  Buffer overflow in TLS handshake
CVE-2024-5678  zlib     1.2.11 HIGH      Integer overflow in inflate

Grype — столбцы: CVE ID, пакет, версия, уровень, EPSS, Risk score:

CVE-2024-1234  openssl  3.0.2  CRITICAL  0.00521  0.0031

Цветовая схема

Уровень Цвет
CRITICAL Красный
HIGH Жёлтый
MEDIUM Синий
LOW Зелёный
NEGLIGIBLE / UNKNOWN Серый

Поведение

  • Автоматически определяет формат отчёта по наличию ключа .Results (Trivy) или .matches (Grype).
  • Если уязвимостей заданного уровня не найдено, выводит подтверждающее сообщение и завершается с кодом 0.
  • Если формат не распознан, завершается с ошибкой и кодом 1.

rootless-docker-audit.sh

Описание

Проводит комплексный аудит rootless-установки Docker и выводит итоговую таблицу с результатами каждой проверки.

Расположение

Rootless Docker Audit/rootless-docker-audit.sh

Зависимости

  • docker
  • Стандартные утилиты: pgrep, ps, stat, grep, uname, awk, lsns, unshare

Использование

./rootless-docker-audit.sh

Скрипт не принимает позиционных аргументов. Поддерживается флаг -h / --help.

Проводимые проверки

# Проверка Что именно проверяется
0 Пользователь dockerd dockerd запущен не от root; скрипт выполняется тем же пользователем
1 CONFIG_USER_NS Наличие CONFIG_USER_NS=y в конфиге ядра /boot/config-$(uname -r)
2 subuid / subgid Записи для текущего пользователя в /etc/subuid и /etc/subgid
3 Вспомогательные утилиты Наличие slirp4netns, fuse-overlayfs, newuidmap, newgidmap
4 cgroup Тип файловой системы /sys/fs/cgroup/ (ожидается cgroup2fs)
5 User namespace Успешное создание namespace через unshare -Ur true
5.1 User namespace (lsns) Наличие user namespace в lsns
6 docker info SecurityOptions содержит rootless; корректность DOCKER_HOST
7 Окружение и сокеты XDG_RUNTIME_DIR установлен; docker.sock доступен по этому пути
8 Сокеты dockerd Наличие сокетов в /run/user/<uid>/docker.sock и $XDG_RUNTIME_DIR/docker.sock
9 Права файлов Права на /etc/subuid и /etc/subgid не превышают 644
10 Переменные окружения DOCKER_DRIVER, DOCKER_ROOTLESS_ROOTLESSKIT_PORT_DRIVER

Пример вывода

🔍 Rootless Docker Audit Script
👤 Текущий пользователь: alice
🧠 Ядро: 6.1.0-21-amd64
--------------------------------------------

[0] Проверка пользователя dockerd:
✅ dockerd запущен без root (rootless mode)

[1] Проверка CONFIG_USER_NS:
✅ CONFIG_USER_NS включён
...
--------------------------------------------
📋 Итоговая таблица аудита:
[OK] dockerd запущен без root (rootless mode)
[OK] CONFIG_USER_NS включён
[FAIL] fuse-overlayfs не найден
--------------------------------------------

Поведение

  • Завершается немедленно с итоговой таблицей, если dockerd не запущен или работает от root.
  • Если обнаружены предупреждения или ошибки, в конце выводится раздел рекомендаций с конкретными действиями по устранению.
  • Каждый результат помечается [OK], [WARN] или [FAIL] и сохраняется для итоговой таблицы.

image-security-checker.sh

Описание

Выполняет статическую проверку безопасности Docker-образов без запуска контейнеров. Образ экспортируется как файловая система и анализируется набором проверок. Поддерживает проверку одного образа или списка из файла.

Расположение

Image Security Checker/image-security-checker.sh

Зависимости

  • docker
  • tar
  • awk
  • stat

Использование

./image-security-checker.sh <имя_образа>
./image-security-checker.sh -f <файл_со_списком>
Аргумент Описание
<имя_образа> Имя или ID Docker-образа (локального или доступного для pull)
-f <файл> Файл со списком образов, по одному на строку; пустые строки и #-комментарии пропускаются

Примеры

Проверка одного образа:

./image-security-checker.sh nginx:1.25

Проверка нескольких образов из файла:

./image-security-checker.sh -f images.txt

Формат файла images.txt:

# продакшн образы
nginx:1.25
myapp:v2.3.1

# базовые образы
registry.example.com/base:latest

Проводимые проверки

# Проверка Критерий прохождения
1 Пользователь по умолчанию USER задан и не равен root или 0; UID/GID пользователя не равны 0
2 Базовый дистрибутив ОС из /etc/*-release — Red OS, Astra Linux или ALT Linux
3 Distroless Отсутствуют: sh/bash/dash, apt/yum/dnf/apk, curl/wget, busybox
4 SUID/SGID файлы Нет файлов с битом SUID (-4000) или SGID (-2000)
5 su / sudo Нет исполняемых файлов su или sudo в образе
6 ENTRYPOINT/CMD от root Стартовый процесс запускается не от root/0
7 Права чувствительных каталогов Права на /etc, /var, /root, /home не превышают 755
8 Чувствительные файлы Нет файлов .npmrc, .gitconfig, id_rsa в образе

Пример вывода

============================================
   Проверка Docker-образа: nginx:1.25
============================================

[FAIL] USER по умолчанию не задан или равен root/0
[FAIL] Базовый дистрибутив не Red OS / Astra Linux / ALT. Найдено: ID=debian
[WARN] Образ не похож на distroless, найдено:
    Найдены shell-утилиты:
        /bin/bash
        /bin/sh
[OK] Файлы с SUID отсутствуют
[OK] Файлы с SGID отсутствуют
[FAIL] ENTRYPOINT (/docker-entrypoint.sh nginx -g daemon off;) запускается под root
[OK] Каталог /etc разрешения: 755
[OK] Чувствительные файлы не найдены

Поведение

  • Для каждого образа создаётся временный контейнер (docker create), файловая система которого экспортируется через docker export и tar во временный каталог.
  • Временный контейнер и рабочий каталог удаляются автоматически при завершении скрипта (в том числе при ошибке) через trap cleanup EXIT.
  • Если базовый дистрибутив распознан как российская ОС (Red OS / Astra Linux / ALT), проверка distroless выдаёт [WARN] вместо [FAIL], поскольку наличие пакетного менеджера допустимо для таких образов.
  • Образы обрабатываются последовательно; сбой проверки одного образа не прерывает обработку остальных.

Участие в разработке

Проект принимает улучшения через pull request. Ниже описаны правила, которых следует придерживаться.

Порядок отправки изменений

  1. Сделайте форк репозитория.
  2. Создайте ветку от main с именем по соглашению (см. ниже).
  3. Внесите изменения, убедитесь что скрипты работают и проходят проверки.
  4. Откройте pull request в ветку main оригинального репозитория с понятным описанием того, что изменилось и зачем.

Именование веток

Префикс Когда использовать
feature/ Новый скрипт или новая функциональность существующего
fix/ Исправление ошибки или некорректного поведения
chore/ Обновление зависимостей, конфигурации, документации без изменения логики

Примеры:

feature/add-network-policy-checker
fix/rootless-audit-false-positive
chore/update-readme-usage-examples

Формат коммитов

Используется стиль Conventional Commits. Сообщение пишется на русском языке.

<тип>: <краткое описание в повелительном наклонении>

Допустимые типы:

Тип Назначение
feat Новая функциональность
fix Исправление ошибки
chore Вспомогательные задачи, рефакторинг без изменения поведения
docs Изменения только в документации

Примеры:

feat: добавить проверку привилегированных контейнеров
fix: исправить парсинг JSON-отчёта при пустом входе
chore: убрать дублирующиеся проверки в аудите rootless
docs: добавить примеры использования в README

Стиль кода для Bash-скриптов

  • Каждый скрипт должен начинаться с set -euo pipefail сразу после шебанга.
  • Перед отправкой PR запустите ShellCheck и устраните все предупреждения:
    shellcheck ваш_скрипт.sh
  • Комментарии в коде пишутся на русском языке.
  • Используйте говорящие имена переменных в нижнем регистре со знаком подчёркивания (image_name, report_file).
  • Выводите сообщения об ошибках в stderr:
    echo "Ошибка: файл не найден" >&2

Тестирование перед PR

Перед открытием pull request вручную проверьте изменённый скрипт на реальном или тестовом Docker-окружении. Убедитесь, что:

  • скрипт отрабатывает штатный сценарий без ошибок;
  • граничные случаи (пустой ввод, несуществующий образ, отсутствие прав) обрабатываются с понятным сообщением и ненулевым кодом выхода;
  • shellcheck не выдаёт предупреждений.

Автор и мейнтейнер проекта — Aleksei Blinov.

About

Useful Scripts

Resources

License

Stars

Watchers

Forks

Contributors

Languages